package com.uwo.commons.datasource.configuration;

import com.alibaba.druid.pool.DruidAbstractDataSource;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 数据源数据配置信息
 * @author hao.yan
 */
@Data
@RefreshScope
@Component("dataSourceProperties")
@ConfigurationProperties(prefix = "spring.datasource")
public class DataSourceProperties {

    private final Logger log = LoggerFactory.getLogger(DataSourceProperties.class);

    public DataSourceProperties(){
        log.debug("dataSourceProperties ===========");
    }

    private PoolProperties poolProperties = new PoolProperties();

    // 数据源信息集合
    private List<SourceProperties> sources;

    // 分库分表规则集合
    private RuleProperties rule;

    // 是否分库分表或多数据源
    private Boolean isMultiSource = false;

    /**
     * 数据源信息
     */
    @Data
    public static class SourceProperties{

        // 名称
        private String name;

        // 地址
        private String url;

        // 用户名
        private String username;

        // 密码
        private String password;

        // 驱动
        private String driverClassName;

        // 分组
        private Integer group = 0;

        // 是否主库
        private Boolean isMaster = true;

    }

    /**
     * 数据源配置
     */
    @Data
    public static class PoolProperties{

        private Integer minIdle = DruidAbstractDataSource.DEFAULT_MIN_IDLE;

        private Integer maxIdle = DruidAbstractDataSource.DEFAULT_MAX_IDLE;

        private Integer maxActive = DruidAbstractDataSource.DEFAULT_MAX_ACTIVE_SIZE;

        private Integer maxWait = DruidAbstractDataSource.DEFAULT_MAX_WAIT;

        private Integer initialSize = DruidAbstractDataSource.DEFAULT_INITIAL_SIZE;

        private Long timeBetweenEvictionRunsMillis = DruidAbstractDataSource.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;

        private Long minEvictableIdleTimeMillis = DruidAbstractDataSource.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;

        private String validationQuery;

        private Boolean testWhileIdle = true;

        private Boolean testOnBorrow = false;

        private Boolean testOnReturn = false;

        private Boolean poolPreparedStatements = false;

        private Integer maxPoolPreparedStatementPerConnectionSize = 20;

        private String filters = "stat,wall,log4j";

    }


    /**
     * 分库分表规则
     */
    @Data
    public static class RuleProperties{

        private StrategyProperties databaseStrategy;

        private StrategyProperties tableStrategy;

        private List<TableProperties> tables;

        private Map<String, MasterSlaveProperties> masterSlaves;

    }

    @Data
    public static class StrategyProperties{

        private String column;

        private String algorithmExpression;

    }

    @Data
    public static class TableProperties{

        private String logicIndex;

        // 表名称
        private String logicTable;

        // 实际表节点
        private String actualDataNodes;

        // 策略
        private StrategyProperties databaseStrategy;

        private StrategyProperties tableStrategy;

        // 主键名称
        private String keyGenerator;

        // 生成主键id 的class类
        private String keyGeneratorClass;

    }

    /**
     * 主从库
     */
    @Data
    public static class MasterSlaveProperties{

        private String masterName;

        private Collection<String> slaveNames = new ArrayList<String>();

    }

}
